
#include <sdk/misc.h>
#include "typeGather.h"
namespace skill {
    bool Airborne::canUse(Game *g, const std::vector<std::string> &params) {
		try
		{
			if(!CoolDownSkill::canUse(g, params)) return false;
			if(params.size() < 3) return false;
			Point p = Point(std::stoi(params[0]), std::stoi(params[1]));
			// @TODO: 范围合法性检测
			// 不过似乎空投是无限距离的
			// 判断目的地是否为空
            if (g->terrain.getType(p.x, p.y) == Terrain::OBSTACLE) return false;
			if (g->entityManager.findActorByPos(p) != nullptr) return false;
			// 判断能量是否足够
			if (std::stoi(params[2]) < 0) return false;
			int cost = FixedAirborneCost + std::stoi(params[2]);
			int energy = std::stoi(origin->properties["energy"]);
			if(energy < cost) return false;
			return true;
		}
		catch(std::exception e)
		{
			return false;
		}
    }

    bool Airborne::use(Game *g, const std::vector<std::string> &params) {
		using namespace entity;
		if(!CoolDownSkill::use(g, params)) return false;
		// 减少自己能量
		int toTransfer = std::stoi(params[2]);
		int cost = FixedAirborneCost + toTransfer;
		int energy = std::stoi(origin->properties["energy"]);
		if (energy < cost) return false;
		Point p = Point(std::stoi(params[0]), std::stoi(params[1]), 0);
        if (g->entityManager.findActorByPos(p) != nullptr) return false;

        // 生成植物
        origin->properties["energy"] = std::to_string(energy - cost);
		Plant *newPlant = g->entityManager.get<BasePlant>();
		newPlant->setPos(p);
        toTransfer = int(std::stoi(params[2]) * AirborneLost + EPS);
        int surgePower = toTransfer / (AirborneTurn + 1);
		int new_energy = toTransfer - surgePower * AirborneTurn;
		newPlant->properties["team"] = origin->properties["team"];
		newPlant->properties["energy"] = std::to_string(new_energy);
        newPlant->learnSkill(new AirborneSurge(surgePower));
		newPlant->useSkill("ReCalculateStats", {});
		return true;
    }

    bool Overload::canUse(Game *g, const std::vector<std::string> &params) {
		if(!CoolDownSkill::canUse(g, params)) return false;
		try
		{
			// 判断能量是否足够
			int cost = OverloadCost;
			int energy = std::stoi(origin->properties["energy"]);
			if(energy < cost) return false;
			return true;
		}
		catch(std::exception e)
		{
			return false;
		}
		return true;
    }

    bool Overload::use(Game *g, const std::vector<std::string> &params) {
		if(!CoolDownSkill::use(g, params)) return false;
		int cost = OverloadCost;
		int energy = std::stoi(origin->properties["energy"]);
		origin->properties["energy"] = std::to_string(energy - cost);
        origin->learnSkill(new OverloadHighBuff);
		return true;
    }

	bool AirborneSurge::use(Game *g, const std::vector<std::string> &params) {
		if (!Buff::use(g, params)) return false;
		try {
			int energy = std::stoi(origin->properties["energy"]);
			energy += power;
			origin->properties["energy"] = std::to_string(energy);
			return true;
		} catch (std::exception) {
			return false;
		}
	}
}